package edu.cuit.zhuyimeng.ticket.service.impl;

import com.alicp.jetcache.Cache;
import com.alicp.jetcache.CacheGetResult;
import edu.cuit.zhuyimeng.flight.api.dto.FlightInfoDTO;
import edu.cuit.zhuyimeng.framework.common.exception.QueryException;
import edu.cuit.zhuyimeng.framework.common.exception.UpdateException;
import edu.cuit.zhuyimeng.ticket.service.IFlightService;
import edu.cuit.zhuyimeng.ticket.service.ITicketSessionManager;
import edu.cuit.zhuyimeng.ticket.service.bo.TicketDispatchSession;
import jakarta.annotation.PostConstruct;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 订票管理实现类
 */
@RequiredArgsConstructor
@Service
@Slf4j
public class TicketSessionManager implements ITicketSessionManager {

    private Map<Long, TicketDispatchSession> ticketSessionMap;
    private final Cache<Long, Date> bookingFlightCache;

    private final RedissonClient redissonClient;

    private final IFlightService flightService;

    @Override
    public boolean buyTicket(FlightInfoDTO flightInfoDTO) {
        if (isActivate(flightInfoDTO.getId())) {
            TicketDispatchSession ticketDispatchSession = ticketSessionMap.get(flightInfoDTO.getId());
            return ticketDispatchSession.addTicket();
        }
        return false;
    }

    @Override
    public boolean refundTicket(FlightInfoDTO flightInfoDTO) {
        if (isActivate(flightInfoDTO.getId())) {
            TicketDispatchSession ticketDispatchSession = ticketSessionMap.get(flightInfoDTO.getId());
            return ticketDispatchSession.removeTicket();
        }
        return false;
    }

    @PostConstruct
    public void initSessionMapFlightInfoDTO() {
        ticketSessionMap = new HashMap<>();
    }

    @Override
    public void openTicketDispatch(FlightInfoDTO flightInfoDTO) {
        if (isActivate(flightInfoDTO.getId())) {
            throw new UpdateException("此航班已经在订票阶段了");
        }
        bookingFlightCache.put(flightInfoDTO.getId(),flightInfoDTO.getEndBook());
        ticketSessionMap.putIfAbsent(flightInfoDTO.getId(), new TicketDispatchSession(flightInfoDTO.getId()
                , flightInfoDTO.getAircraftInfoDTO().getCapacity(), redissonClient));
    }

    @Override
    public void closeTicketDispatch(Long flightId) {
        if (!isActivate(flightId)) {
            return;
        }
        TicketDispatchSession ticketDispatchSession = ticketSessionMap.get(flightId);
        if (ticketDispatchSession != null ){
            ticketDispatchSession.close();
            ticketSessionMap.remove(flightId);
        }
        bookingFlightCache.remove(flightId);
    }

    @Override
    public boolean isSoldOut(Long flightID) {
        if (!isActivate(flightID)) {
            throw new QueryException("当前航班不在售票状态");
        }
        return ticketSessionMap.get(flightID).isSoldOut();
    }

    public TicketDispatchSession getTicketDispatchSession(Long flightId) {
        if (isActivate(flightId)) {
            return ticketSessionMap.get(flightId);
        }
        return null;
    }

    private boolean isActivate(Long flight) {
        CacheGetResult<Date> result = bookingFlightCache.GET(flight);
        if (result.isSuccess()) {
            if (!ticketSessionMap.containsKey(flight)) {
                FlightInfoDTO flightInfoDTO = flightService.queryFlightInfo(flight);
                ticketSessionMap.put(flightInfoDTO.getId(), new TicketDispatchSession(flightInfoDTO.getId()
                        , flightInfoDTO.getAircraftInfoDTO().getCapacity(), redissonClient));
            }
            return true;
        }
        return false;
    }
}
